package com.jjc.android

import android.os.Build
import com.jjc.android.base.BaseActivity
import com.jjc.android.dialog.LoadingDialog
import com.jjc.android.entity.*
import com.jjc.android.net.SimpleHttpCallback
import com.jjc.android.util.*
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Progress
import java.io.File

object GlobalManager {
    var isNotSupportRaw:Boolean by defSP("is_not_support_raw",false)
    var userAgreement: String by defACache("user_agreement", "")
    var privacyPolicy: String by defACache("privacy_policy", "")
    var aboutUs: String by defACache("about_us", "")
    var userAgreementEn: String by defACache("user_agreement_en", "")
    var privacyPolicyEn: String by defACache("privacy_policy_en", "")
    var aboutUsEn: String by defACache("about_us_en", "")
    var guideImages: ArrayList<String> by defACache("guide_image", ArrayList())
    var guideImagesEn: ArrayList<String> by defACache("guide_image_en", ArrayList())
    var languageId:Int by defSP("language",MultiLanguageUtil.LANGUAGE_SYSTEM)

    var isShowDebugInfo = false


    fun getAboutUsContent():String{
        return if(MultiLanguageUtil.getInstance().isEnglish) aboutUsEn else aboutUs
    }

    fun getUserAgreementContent():String{
        return if(MultiLanguageUtil.getInstance().isEnglish) userAgreementEn else userAgreement
    }

    fun getPrivacyPolicyContent():String{
        return if(MultiLanguageUtil.getInstance().isEnglish) privacyPolicyEn else privacyPolicy
    }


    fun fetchAppInfo(){
        OkGo.post<LzyResponse<UserInfo>>(Constants.getTuoTuToken)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<UserInfo>>(false, isThird = true){
                override fun onCallSuccess(response: LzyResponse<UserInfo>) {
                    fetchAppInfoByToken(response.data?.tuoTuToken)
                }

                override fun onCallError(error: String?) {
                    super.onCallError(error)
                    fetchAppInfoByToken(null)
                }
            })

    }

    private fun fetchAppInfoByToken(token:String?){
        val tuotuToken = token.let { if(it.isNullOrEmpty()){
            if(UserManager.isLogin()) UserManager.userInfo().tuoTuToken else Constants.TEMP_TOKEN
        }else{
            it
        } }
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "19bfbf3e55fc436fb56b6e8b58b8b51b","filters" to listOf<KeyValuePair>(
                KeyValuePair("xjxmcth0zw6isyy9","1268b839-540d-4eb5-b69a-d923b7fc98f6"),
                KeyValuePair("qazczzminvqag3uh","a6e31548-e159-4e2e-8bcd-fa128608bd1e")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false, isThird = true){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.privacyPolicy?.let {
                        if(!it.isNullOrEmpty()){
                            privacyPolicy = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "7cd85796e89f4c808cbf6ad0418f9db3","filters" to listOf<KeyValuePair>(
                KeyValuePair("68zh7koqmbrui0un","ebc44d27-10d7-49a0-be32-d5fedf38b07a")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false, isThird = true){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.aboutUs?.let {
                        if(!it.isNullOrEmpty()){
                            aboutUs = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "19bfbf3e55fc436fb56b6e8b58b8b51b","filters" to listOf<KeyValuePair>(
                KeyValuePair("xjxmcth0zw6isyy9","1268b839-540d-4eb5-b69a-d923b7fc98f6"),
                KeyValuePair("qazczzminvqag3uh","770a5bc1-7f01-42a1-b9c1-0eb71b998fe0"),
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.privacyPolicy?.let {
                        if(!it.isNullOrEmpty()){
                            userAgreement = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "19bfbf3e55fc436fb56b6e8b58b8b51b","filters" to listOf<KeyValuePair>(
                KeyValuePair("xjxmcth0zw6isyy9","d188f4a0-52dd-4e19-806e-f0ae8087765b"),
                KeyValuePair("qazczzminvqag3uh","e1bfc897-248e-4b84-9720-b93222f77406")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false, isThird = true){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.privacyPolicy?.let {
                        if(!it.isNullOrEmpty()){
                            privacyPolicyEn = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "7cd85796e89f4c808cbf6ad0418f9db3","filters" to listOf<KeyValuePair>(
                KeyValuePair("68zh7koqmbrui0un","fc53d4e5-2d1f-4fb6-a301-c3be273a60cf")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false, isThird = true){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.aboutUs?.let {
                        if(!it.isNullOrEmpty()){
                            aboutUsEn = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 1,"needpage" to "1","formheaduuid" to "19bfbf3e55fc436fb56b6e8b58b8b51b","filters" to listOf<KeyValuePair>(
                KeyValuePair("xjxmcth0zw6isyy9","d188f4a0-52dd-4e19-806e-f0ae8087765b"),
                KeyValuePair("qazczzminvqag3uh","46a7d960-dd88-42aa-8f0a-f55ab4cc8bc8"),
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.privacyPolicy?.let {
                        if(!it.isNullOrEmpty()){
                            userAgreementEn = it
                        }
                    }

                }
            })
        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 100,"needpage" to "1","formheaduuid" to "18f72e99181143ad88d21716e1a25583","filters" to listOf<KeyValuePair>(
                KeyValuePair("68zh7koqmbrui0un","cee4177d-9923-4d4e-9a90-95edeaea7b0f")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.sdxltcmsgmmj1csv?.let {
                        if(!it.isNullOrEmpty()){
                            guideImages = ArrayList<String>().apply {
                                addAll(it.map { it.url })
                            }
                        }
                    }

                }
            })

        OkGo.post<LzyResponse<PageInfo<AppDto>>>(Constants.getFormList)
            .headers("Authorization",tuotuToken)
            .paramEx(mutableMapOf("page" to 1,"pagesize" to 100,"needpage" to "1","formheaduuid" to "18f72e99181143ad88d21716e1a25583","filters" to listOf<KeyValuePair>(
                KeyValuePair("68zh7koqmbrui0un","e697063d-b644-4e60-add8-91b793d2ad04")
            )),true)
            .tag(this)
            .execute(object : SimpleHttpCallback<LzyResponse<PageInfo<AppDto>>>(false){
                override fun onCallSuccess(response: LzyResponse<PageInfo<AppDto>>) {
                    response.data.first?.sdxltcmsgmmj1csv?.let {
                        if(!it.isNullOrEmpty()){
                            guideImagesEn = ArrayList<String>().apply {
                                addAll(it.map { it.url })
                            }
                        }
                    }

                }
            })
    }


    fun uploadException(imageUrl:String,imageFormat:String,uploadTime:Long,tcTime:Long){
        OkGo.post<LzyResponse<String>>(Constants.reportEx)
            .paramEx(
                mutableMapOf(
                "phoneModel" to Build.MODEL,
                "systemVersion" to Build.VERSION.RELEASE,
                "mobileBrand" to Build.BRAND,
                "imageFormat" to imageFormat,
                "imageFile" to imageUrl,
                "tcTime" to tcTime,
                "uploadTime" to uploadTime)
            )
            .execute(object : SimpleHttpCallback<LzyResponse<String>>(false){
                override fun onCallSuccess(response: LzyResponse<String>) {
                }

                override fun onCallError(error: String?) {
                    super.onCallError(error)
                }
            })
    }

    var isSupportRaw:Boolean = false


    //this.is_oneplus = Build.MANUFACTURER.toLowerCase(Locale.US).contains("oneplus");
    val is_samsung = Build.MANUFACTURER.lowercase().contains("samsung")
    val is_samsung_s7 = Build.MODEL.lowercase().contains("sm-g93")
    val is_samsung_galaxy_s = is_samsung && Build.MODEL.lowercase().contains("sm-g")

    val isSpecialMobileBrands by lazy {
        val mobileString = deviceInfo()
        specialMobileBrands.contains(mobileString)
    }

    @JvmStatic
    fun deviceInfo():String{
        return "${Build.BRAND.lowercase()}-${Build.MODEL.lowercase()}-${Build.DEVICE.lowercase()}"
    }

    private val specialMobileBrands = listOf(
        "vivo-v2055a-pd2055",
        "vivo-v1962a-pd1962",
        "oneplus-php110-op5927",
        "xiaomi-m2101k9c-renoir",
        "xiaomi-mi 10 pro-cmi",
        "oneplus-le2100-oneplus9r",
        "oppo-pbbm00-pbbm00",
        "xiaomi-m2102j2sc-thyme",
        "oneplus-kb2000-oneplus8t",
        "oneplus-le2100-oneplus9r",
//        "huawei-vtr-al00-hwvtr",
        "oppo-pclm10-op4a89",
        "xiaomi-mi 10-umi",
        "redmi-21091116c-pissarro",
        "oppo-pclm10-op4a89",
        "xiaomi-m2011k2c-venus"
//        , "oppo-peqm00-op4ed5"
    )

    fun genrateExposureTime(min_exposure_time:Long,max_exposure_time:Long):List<Long> {
        var seekbar_values: ArrayList<Long> = ArrayList()
        seekbar_values.add(min_exposure_time)
        // 1/10,000 to 1/1,000
        for (i in 10 downTo 1)
        {
            val exposure: Long = 1000000000L / (i * 1000L)
            if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                exposure
            )
        }
        // 1/900 to 1/100
        for (i in 9 downTo 1)
        {
            val exposure: Long = 1000000000L / (i * 100L)
            if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                exposure
            )
        }
        // 1/90 to 1/60 (steps of 10)
        for (i in 9 downTo 6)
        {
            val exposure: Long = 1000000000L / (i * 10L)
            if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                exposure
            )
        }
        // 1/50 to 1/10 (steps of 5)
        run {
            var i = 50
            while (i >= 10) {
                val exposure = 1000000000L / i
                if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                    exposure
                )
                i -= 5
            }
        }

        // 0.1 to 1.9, per 1.0s
        for (i in 1 .. 19)
        {
            val exposure: Long = 1000000000L / 10 * i
            if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                exposure
            )
        }
        // 2 to 19, per 1s
        for (i in 2 .. 19)
        {
            val exposure: Long = 1000000000L * i
            if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                exposure
            )
        }
        // 20 to 60, per 5s
        run {
            var i = 20
            while (i < 60) {
                val exposure = 1000000000L * i
                if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                    exposure
                )
                i += 5
            }
        }

        // n.b., very long exposure times are not widely supported, but requested at https://sourceforge.net/p/opencamera/code/merge-requests/49/
        // 60 to 180, per 15s
        run {
            var i = 60
            while (i < 180) {
                val exposure = 1000000000L * i
                if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                    exposure
                )
                i += 15
            }
        };
        // 180 to 600, per 60s
        run {
            var i = 180
            while (i < 600) {
                val exposure = 1000000000L * i
                if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                    exposure
                )
                i += 60
            }
        }
        // 600 to 1200, per 120s
        run {
            var i = 600
            while (i <= 1200) {
                val exposure = 1000000000L * i
                if (exposure in (min_exposure_time + 1) until max_exposure_time) seekbar_values.add(
                    exposure
                )
                i += 120
            }
        }
        return seekbar_values
    }


    fun genrateIso(min_iso:Int,max_iso:Int):List<Int> {
        val seekbar_values: ArrayList<Int> = ArrayList<Int>()
        seekbar_values.add(min_iso)
        // 1 to 99, per 1
        for (i in 1..99) {
            if (i in (min_iso + 1) until max_iso) seekbar_values.add(i)
        }
        // 100 to 500, per 5
        run {
            var i = 100
            while (i < 500) {
                if (i in (min_iso + 1) until max_iso) seekbar_values.add(i)
                i += 5
            }
        }
        // 500 to 1000, per 10
        run {
            var i = 500
            while (i < 1000) {
                if (i in (min_iso + 1) until max_iso) seekbar_values.add(i)
                i += 10
            }
        }
        // 1000 to 5000, per 50
        run {
            var i = 1000
            while (i < 5000) {
                if (i in (min_iso + 1) until max_iso) seekbar_values.add(i)
                i += 50
            }
        }
        // 5000 to 10000, per 100
        run {
            var i = 5000
            while (i < 10000) {
                if (i in (min_iso + 1) until max_iso) seekbar_values.add(i)
                i += 100
            }
        }
        return seekbar_values
    }

    fun uploadFile(context: BaseActivity,showLoading:Boolean , file: File, errorAction:((String?)->Unit)? = null, action: (String,String) -> Unit){
//        if(BuildConfig.DEBUG){
//            action.invoke("13511111111023080216434003.jpg","http://106.54.213.16/upload/13511111111023080216434003.jpg")
//            return
//        }
        var loading:LoadingDialog? = null
        if(showLoading){
            loading = LoadingDialog(context,context.getString(R.string.upload_file_txt))
            loading.show()
        }
        OkGo
            .post<LzyResponse<Any>>(Constants.upload)
            .isMultipart(true)
            .params("image",file)
            .tag(context)
            .execute(object : SimpleHttpCallback<LzyResponse<Any>>(false){
                override fun onCallSuccess(response: LzyResponse<Any>) {
                    if(response.img_file_path.isNullOrEmpty()||response.image_filename.isNullOrEmpty()){
                        errorAction?.invoke(response.msg)
                    }else{
                        action.invoke(response.image_filename,response.img_file_path)
                    }
                    loading?.dismiss()
                }

                override fun uploadProgress(progress: Progress?) {
                    super.uploadProgress(progress)
                    progress?.let {
                        loading?.setMessage(String.format("%s\n%s/%s",context.getString(R.string.upload_file_txt),FileUtil.getReadableFileSize(progress.currentSize),FileUtil.getReadableFileSize(progress.totalSize)))
                    }

                }

                override fun onCallError(error: String?) {
                    super.onCallError(error)
                    errorAction?.invoke(error)
                    loading?.dismiss()
                }
            })
    }

}